﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Pigs.Enemies;
using Pigs.Weapons;

namespace pigs
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Level : GameScreen
    {
        public String levelName;
        public SpriteBatch spriteBatch;
        public SpriteFont scoreFont;

        public List<Player> players;

        public Texture2D explosionTexture;
        public Texture2D basicPigTexture;
        public Texture2D slopTexture;
        public Texture2D starTexture;
        public Texture2D cornTexture;
        public Texture2D ScoreArea;
        public Texture2D heartTexture;
        public Texture2D steelPigTexture;
        public Texture2D suiPig;
        public Texture2D bunnyPigTexture;
        public Texture2D drunkPig;
        public Texture2D ninjaPig;
        public Texture2D magicPig;
        public Texture2D leaderPig;

        public List<Pig> pigs;
        public List<Pig> newBunnies;
        public List<Slop> slops;
        public List<Corn> cornBullets;
        public List<Star> ninjaStars;
        public List<Scenery> background;
        public List<Scenery> collidableBackground;
        public List<PowerUp> powerups;
        public List<Explosion> explosions;

        public SoundEffectInstance pigDyingSound;
        public SoundEffectInstance explosionSound;

        // Keyboard states used to determine key presses
        public KeyboardState currentKeyboardState;
        public KeyboardState previousKeyboardState;

        // Gamepad states used to determine button presses
        public GamePadState currentGamePad1State;
        public GamePadState previousGamePad1State;
        public GamePadState currentGamePad2State;
        public GamePadState previousGamePad2State;
        public GamePadState currentGamePad3State;
        public GamePadState previousGamePad3State;
        public GamePadState currentGamePad4State;
        public GamePadState previousGamePad4State;

        public long gp1RumbleEndTime;
        public long gp2RumbleEndTime;
        public long gp3RumbleEndTime;
        public long gp4RumbleEndTime;

        public int SCORE_SPACE;

        public ContentManager content;
        
        public float pauseAlpha;
        public Viewport viewport;

        public Random rand;
        public int POWERUP_CHANCE;

        // Keep the amount of steel pigs to a value of 1 at any given time
        public bool steelPigPresent;
        public bool leaderPigPresent;

        public Boolean[] wave;
        public long levelTime;
        public Boolean updateBackgrounds;

        int lives;
        public int CurWave;

        // Keep track of the amount of pigs that have escaped
        public int escaped;
        protected GameSettings settings;

        public Level(GameSettings set)
        {
            settings = set;

            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);
        }

        /// <summary>
        /// load content common to all levels
        /// </summary>
        public void loadCommonContent()
        {            

            gp1RumbleEndTime = 0;
            gp2RumbleEndTime = 0;
            gp3RumbleEndTime = 0;
            gp4RumbleEndTime = 0;

            SCORE_SPACE = 30;

            pigs = new List<Pig>();
            newBunnies = new List<Pig>();
            background = new List<Scenery>();
            collidableBackground = new List<Scenery>();
            slops = new List<Slop>();
            ninjaStars = new List<Star>();
            cornBullets = new List<Corn>();
            powerups = new List<PowerUp>();
            explosions =  new List<Explosion>();
            viewport = ScreenManager.GraphicsDevice.Viewport;
            spriteBatch = ScreenManager.SpriteBatch;
            rand = new Random();

            this.ScoreArea = new Texture2D(ScreenManager.GraphicsDevice, viewport.Width, SCORE_SPACE);

            Color[] data = new Color[viewport.Width * SCORE_SPACE];
            for (int i = 0; i < data.Length; ++i) data[i] = Color.Black;
            this.ScoreArea.SetData(data);

            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            //Set the font
            scoreFont = content.Load<SpriteFont>("fonts/SpriteFont1");

            //load sounds
            SoundEffect pig = content.Load<SoundEffect>("sounds/pigDeath");
            pigDyingSound = pig.CreateInstance();
            SoundEffect explosion = content.Load<SoundEffect>("sounds/explosion");
            explosionSound = explosion.CreateInstance();

            explosionTexture = content.Load<Texture2D>("weapons/explosion");
            heartTexture = content.Load<Texture2D>("player/heart");
            basicPigTexture = content.Load<Texture2D>("enemies/flypig");
            steelPigTexture = content.Load<Texture2D>("enemies/steelpig");
            slopTexture = content.Load<Texture2D>("weapons/slop2");
            cornTexture = content.Load<Texture2D>("weapons/corngrid");
            starTexture = content.Load<Texture2D>("weapons/Star");
            suiPig = content.Load<Texture2D>("enemies/kamikaze");
            bunnyPigTexture = content.Load<Texture2D>("enemies/bunnypig");
            drunkPig = content.Load<Texture2D>("enemies/drunkpig");
            ninjaPig = content.Load<Texture2D>("enemies/ninjapig");
            magicPig = content.Load<Texture2D>("enemies/magicpig");
            leaderPig = content.Load<Texture2D>("enemies/generalpig");


            this.createPlayers();

            this.lives = 30;

            steelPigPresent = false;
            leaderPigPresent = false;

            for (int i = 0; i < wave.Length; i++)
            {
                wave[i] = false;
            }

            updateBackgrounds = true;

            this.ScreenManager.Game.ResetElapsedTime();
            levelTime = 0;

            this.POWERUP_CHANCE = 25;
            if (this.settings.numberOfPlayers == 2) POWERUP_CHANCE = 20;
            if (this.settings.numberOfPlayers == 3) POWERUP_CHANCE = 16;
            if (this.settings.numberOfPlayers == 4) POWERUP_CHANCE = 13;
            if (this.settings.numberOfPlayers == 5) POWERUP_CHANCE = 10;
        }

        public void createPlayers()
        {
            players = new List<Player>();

            //load images
            Texture2D playerTexture = content.Load<Texture2D>("player/blimpgrid");
            Texture2D aimerTexture = content.Load<Texture2D>("player/smallcrosshairs");

            //initialize player and aimer
            Player player = new Player(playerTexture, new Vector2(300, 150));
            player.Initialize(aimerTexture, new Vector2(200, 130), content, 1, 1.5f, settings.playSound);
            player.setBounds(0, viewport.Width, SCORE_SPACE, viewport.Height);
            player.reset = false;

            players.Add(player);

            if (settings.numberOfPlayers > 1)
            {
                playerTexture = content.Load<Texture2D>("player/blimpgreen");
                aimerTexture = content.Load<Texture2D>("player/crosshairs3");
                player = new Player(playerTexture, new Vector2(200, 100));
                player.Initialize(aimerTexture, new Vector2(200, 130), content, 1.5f, 2, settings.playSound);
                player.setBounds(0, viewport.Width, SCORE_SPACE, viewport.Height);
                player.reset = false;
                players.Add(player);

            }

            if (settings.numberOfPlayers > 2)
            {
                playerTexture = content.Load<Texture2D>("player/blimpred");
                aimerTexture = content.Load<Texture2D>("player/crosshairs2");
                player = new Player(playerTexture, new Vector2(200, 200));
                player.Initialize(aimerTexture, new Vector2(200, 130), content, 1.5f, 2, settings.playSound);
                player.setBounds(0, viewport.Width, SCORE_SPACE, viewport.Height);
                player.reset = false;
                players.Add(player);
            }

            if (settings.numberOfPlayers > 3)
            {
                playerTexture = content.Load<Texture2D>("player/blimppink");
                aimerTexture = content.Load<Texture2D>("player/crosshairs4");
                player = new Player(playerTexture, new Vector2(100, 50));
                player.Initialize(aimerTexture, new Vector2(200, 130), content, 1.5f, 2, settings.playSound);
                player.setBounds(0, viewport.Width, SCORE_SPACE, viewport.Height);
                player.reset = false;
                players.Add(player);
            }

            if (settings.numberOfPlayers > 4)
            {
                playerTexture = content.Load<Texture2D>("player/blimporange");
                aimerTexture = content.Load<Texture2D>("player/crosshairs5");
                player = new Player(playerTexture, new Vector2(100, 250));
                player.Initialize(aimerTexture, new Vector2(200, 130), content, 1.5f, 2, settings.playSound);
                player.setBounds(0, viewport.Width, SCORE_SPACE, viewport.Height);
                player.reset = false;
                players.Add(player);
            }

        }

        /// <summary>
        /// Lets the game respond to player input. Unlike the Update method,
        /// this will only be called when the gameplay screen is active.
        /// </summary>
        public override void HandleInput(InputState input)
        {

            if (input == null)
                throw new ArgumentNullException("input");

            // Look up inputs for the active player profile.
            int playerIndex = (int)ControllingPlayer.Value;


            KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex];
            GamePadState gamePadState = input.CurrentGamePadStates[playerIndex];

            // The game pauses either if the user presses the pause button, or if
            // they unplug the active gamepad. This requires us to keep track of
            // whether a gamepad was ever plugged in, because we don't want to pause
            // on PC if they are playing with a keyboard and have no gamepad at all!
            bool gamePadDisconnected = !gamePadState.IsConnected &&
                                       input.GamePadWasConnected[playerIndex];

            if (gamePadDisconnected || input.IsPauseGame(null))
            {
                ScreenManager.AddScreen(new PauseMenuScreen(settings), null);
            }
        }

        public void updatePlayers(GameTime gameTime)
        {
            // Save the previous state of the keyboard and game pad so we can determinesingle key/button presses
            previousGamePad1State = currentGamePad1State;
            previousKeyboardState = currentKeyboardState;
            previousGamePad2State = currentGamePad2State;
            previousGamePad3State = currentGamePad3State;
            previousGamePad4State = currentGamePad4State;

            // Read the current state of the keyboard and gamepad and store it
            currentKeyboardState = Keyboard.GetState();
            currentGamePad1State = GamePad.GetState(PlayerIndex.One);
            currentGamePad2State = GamePad.GetState(PlayerIndex.Two);
            currentGamePad3State = GamePad.GetState(PlayerIndex.Three);
            currentGamePad4State = GamePad.GetState(PlayerIndex.Four);

            MouseState mouse = Mouse.GetState();

            if (settings.numberOfPlayers == 1)
            {
                // Update the player
                players[0].Update(gameTime, currentKeyboardState, previousKeyboardState, settings);
                players[0].Update(gameTime, currentGamePad1State, previousGamePad1State, settings);
                if (settings.useMouse)
                {
                    players[0].Update(mouse, gameTime);
                    if (mouse.RightButton == ButtonState.Pressed) { addSlop(players[0], gameTime); }
                }
            }
            if (settings.numberOfPlayers > 1)
            {
                if (settings.useKeyboard)
                {
                    players[0].Update(gameTime, currentKeyboardState, previousKeyboardState, settings);
                    players[1].Update(gameTime, currentGamePad1State, previousGamePad1State, settings);
                    if (settings.useMouse)
                    {
                        players[0].Update(mouse, gameTime);
                        if (mouse.RightButton == ButtonState.Pressed) { addSlop(players[0], gameTime); }
                    }
                }
                else
                {
                    players[0].Update(gameTime, currentGamePad1State, previousGamePad1State, settings);
                    players[1].Update(gameTime, currentGamePad2State, previousGamePad2State, settings);
                }
            }
            if (settings.numberOfPlayers > 2)
            {
                if (settings.useKeyboard)
                {
                    players[2].Update(gameTime, currentGamePad2State, previousGamePad2State, settings);
                }
                else
                {
                    players[2].Update(gameTime, currentGamePad3State, previousGamePad3State, settings);
                }
            }
            if (settings.numberOfPlayers > 3)
            {
                if (settings.useKeyboard)
                {
                    players[3].Update(gameTime, currentGamePad3State, previousGamePad3State, settings);
                }
                else
                {
                    players[3].Update(gameTime, currentGamePad4State, previousGamePad4State, settings);
                }
            }
            if (settings.numberOfPlayers > 4)
            {
                players[4].Update(gameTime, currentGamePad4State, previousGamePad4State, settings);
                players[4].finishUpdate(gameTime);
            }
            foreach (Player p in players) { p.finishUpdate(gameTime); }

        }

        public void updateRumble()
        {
            if (gp1RumbleEndTime < levelTime) GamePad.SetVibration(PlayerIndex.One, 0f, 0f);
            if (gp2RumbleEndTime < levelTime) GamePad.SetVibration(PlayerIndex.Two, 0f, 0f);
            if (gp3RumbleEndTime < levelTime) GamePad.SetVibration(PlayerIndex.Three, 0f, 0f);
            if (gp4RumbleEndTime < levelTime) GamePad.SetVibration(PlayerIndex.Four, 0f, 0f);
        }

        public void updateNonPlayers(GameTime gameTime)
        {
            if (updateBackgrounds)
            {
                // Update backround positions
                foreach (Scenery b in background) { b.Update(); }
                foreach (Scenery b in collidableBackground) { b.Update(); }
            }

            updateBullets();

            SteelPig steelPig = null;
            Leader_Pig leadPig = null;

            foreach (Pig p in pigs)
            {
                if (p.ID.Equals("steel")) { steelPig = (SteelPig)p; }
                if (p.ID.Equals("leader")) { leadPig = (Leader_Pig)p; }
            }


            foreach (Pig p in pigs)
            {
                if (p.ID.Equals("suicide")) { p.suiUpdate(gameTime, this.collidableBackground, getLowestPlayer().position); }
                else if (p.ID.Equals("basic")) { p.basicUpdate(gameTime, steelPig, this.steelPigPresent, this.pigs, this.collidableBackground); }
                else if (p.ID.Equals("drunk")) { p.drunkUpdate(gameTime); }
                else if (p.ID.Equals("ninja")) 
                {
                    Vector2 tmp = p.center();
                    foreach (Player q in players)
                    {
                        if (p.ninjaUpdate(gameTime, q.bullets, this.collidableBackground, this.pigs))
                        {
                            Explosion e1 = new Explosion(explosionTexture, p.center(), 1);
                            Explosion e2 = new Explosion(explosionTexture, tmp, 1);
                            explosions.Add(e1);
                            explosions.Add(e2);
                        }
                    }
                }
                else if (p.ID.Equals("magic")) { p.magicUpdate(gameTime, collidableBackground, players, this.pigs, steelPigPresent); }
                else if (p.ID.Equals("bunny")) 
                {
                    if (p.bunnyUpdate(gameTime, this.collidableBackground, this.pigs, this.leaderPigPresent, leadPig))
                    {
                        if (!this.leaderPigPresent && pigs.Count < 100)
                        {
                            Bunny_Pig newSpawned = new Bunny_Pig(bunnyPigTexture, p.position, settings.numberOfPlayers);
                            newBunnies.Add(newSpawned);
                        }
                        else if (this.leaderPigPresent && pigs.Count < 100)
                        {
                            Bunny_Pig newSpawned = new Bunny_Pig(bunnyPigTexture, new Vector2(p.position.X - 25, p.position.Y - 25), settings.numberOfPlayers);
                            newBunnies.Add(newSpawned);
                        }
                    }
                }
                else if (p.ID.Equals("steel")) { p.steelUpdate(gameTime, collidableBackground, (int)getLowestPlayer().position.Y); }
                else if (p.ID.Equals("leader")) { p.leaderUpdate(gameTime, collidableBackground, this.pigs); }
                else { p.Update(gameTime); }
                p.position.Y = MathHelper.Clamp(p.position.Y, SCORE_SPACE, viewport.Height - p.Height);
            }
            foreach (Pig p in newBunnies)
            {
                pigs.Add(p);
            }
            newBunnies.Clear();

            foreach (Explosion e in explosions) { e.Update(); }
            foreach (PowerUp p in powerups) { p.Update(gameTime); }

            foreach (Pig p in pigs)
            {
                // Basic pigs throw corn
                if (p.ID.Equals("basic"))
                {

                    if (rand.Next(0, 100) == 1)
                    {
                        Vector2 start = new Vector2(p.position.X, p.position.Y + p.Height / 2);
                        Corn c = new Corn(cornTexture, start);
                        c.Initialize(-1 * new Vector2(rand.Next(3, 6), rand.Next(10, 20)));
                        if (p.buff)
                        {
                            c.damage += 3;
                        }
                        this.cornBullets.Add(c);
                    }
                }
                else if (p.ID.Equals("ninja"))
                {
                    if(p.cooldown_ninja < 1)
                    {
                        int i = rand.Next(settings.numberOfPlayers);
                        if(Vector2.Distance(players[i].position, p.position) > 300)
                        {
                            Star s = new Star(starTexture, p.position);
                            s.Initialize(players[i].position, p.position);
                            if (p.buff)
                            {
                                s.damage += 3;
                            }
                            this.ninjaStars.Add(s);
                        }
                    }
                }
                // While we're iterating, if the pig would go off the top or bottom of the screen, prevent it from happening
                if ((p.position.Y - viewport.Y < 10) && p.vertSpeed < 0) { p.vertSpeed = 1; }
                else if ((viewport.Y - (p.position.Y + p.texture.Height) < 10) && p.vertSpeed > 0) { p.vertSpeed = 0; }

            }
        }

        /// <summary>
        /// update all items in game and check for collisions
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public void commonUpdate(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);

            // Gradually fade in or out depending on whether we are covered by the pause screen.
            if (coveredByOtherScreen) { pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1); }
            else { pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0); }

            if (IsActive)
            {
                updatePlayers(gameTime);
                updateNonPlayers(gameTime);
                updateRumble();

                foreach (Player p in players)
                {
                    if (p.alive)
                    {
                        playerCollisions(p, gameTime);
                        bulletCollisions(gameTime, p);
                    }
                }

                if (settings.friendlyFire) { bulletPlayerCollisions(); }

                fireSlops(gameTime);
                cornCollisions();
                starCollisions();
                PigSceneryCollision();

                removeInActive();

                if (allPlayersDead()) doEndGame(false);

                //levelTime = (gameTime.TotalGameTime.Ticks - levelStartTime) / 10000;
                levelTime = (gameTime.ElapsedGameTime.Ticks/10000 + levelTime);
            }
        }

        public void fireSlops(GameTime gameTime)
        {
            if (settings.numberOfPlayers == 1)
            {
                if (currentKeyboardState.IsKeyDown(Keys.F) || currentGamePad1State.IsButtonDown(Buttons.LeftTrigger))
                {
                    this.addSlop(players[0], gameTime);
                }
            }
            else if (settings.useKeyboard)
            {
                if (currentKeyboardState.IsKeyDown(Keys.F)) this.addSlop(players[0], gameTime);
                if (currentGamePad1State.IsButtonDown(Buttons.LeftTrigger) && settings.numberOfPlayers > 1) this.addSlop(players[1], gameTime);
                if (currentGamePad2State.IsButtonDown(Buttons.LeftTrigger) && settings.numberOfPlayers > 2) this.addSlop(players[2], gameTime);
                if (currentGamePad3State.IsButtonDown(Buttons.LeftTrigger) && settings.numberOfPlayers > 3) this.addSlop(players[3], gameTime);
                if (currentGamePad4State.IsButtonDown(Buttons.LeftTrigger) && settings.numberOfPlayers > 4) this.addSlop(players[4], gameTime);
            }
            else
            {
                if (currentGamePad1State.IsButtonDown(Buttons.LeftTrigger)) this.addSlop(players[0], gameTime);
                if (currentGamePad2State.IsButtonDown(Buttons.LeftTrigger) && settings.numberOfPlayers > 1) this.addSlop(players[1], gameTime);
                if (currentGamePad3State.IsButtonDown(Buttons.LeftTrigger) && settings.numberOfPlayers > 2) this.addSlop(players[2], gameTime);
                if (currentGamePad4State.IsButtonDown(Buttons.LeftTrigger) && settings.numberOfPlayers > 3) this.addSlop(players[3], gameTime);
            }

        }

        public void applyRumble(Player p, float left, float right, int time)
        {
            if (!settings.useRumble) return;
            if ((p.Equals(players[0]) && !settings.useKeyboard) || settings.numberOfPlayers == 1)
            {
                GamePad.SetVibration(PlayerIndex.One, left, right);
                gp1RumbleEndTime = levelTime + time;
            }
            if (settings.numberOfPlayers > 1 && p.Equals(players[1]) && !settings.useKeyboard)
            {
                GamePad.SetVibration(PlayerIndex.Two, left, right);
                gp2RumbleEndTime = levelTime + time;
            }
            if (settings.numberOfPlayers > 1 && p.Equals(players[1]) && settings.useKeyboard)
            {
                GamePad.SetVibration(PlayerIndex.One, left, right);
                gp1RumbleEndTime = levelTime + time;
            }
            if (settings.numberOfPlayers > 2 && p.Equals(players[2]) && !settings.useKeyboard)
            {
                GamePad.SetVibration(PlayerIndex.Three, left, right);
                gp3RumbleEndTime = levelTime + time;
            }
            if (settings.numberOfPlayers > 2 && p.Equals(players[2]) && settings.useKeyboard)
            {
                GamePad.SetVibration(PlayerIndex.Two, left, right);
                gp2RumbleEndTime = levelTime + time;
            }
            if (settings.numberOfPlayers > 3 && p.Equals(players[3]) && !settings.useKeyboard)
            {
                GamePad.SetVibration(PlayerIndex.Four, left, right);
                gp4RumbleEndTime = levelTime + time;
            }
            if (settings.numberOfPlayers > 3 && p.Equals(players[3]) && settings.useKeyboard)
            {
                GamePad.SetVibration(PlayerIndex.Three, left, right);
                gp3RumbleEndTime = levelTime + time;
            }
            if (settings.numberOfPlayers > 4 && p.Equals(players[4]) && settings.useKeyboard)
            {
                GamePad.SetVibration(PlayerIndex.Four, left, right);
                gp4RumbleEndTime = levelTime + time;
            } 
        }

        public void playerCollisions(Player player, GameTime gameTime)
        {
            foreach (PowerUp p in powerups)
            {
                if (p.rectangle.Intersects(player.rectangle)) { applyPowerUp(player, p); }
            }

            if (player.active)
            {
                // Collision detection between the player and pigs
                foreach (DynamicObject p in pigs)
                {
                    if (player.checkCollision(p))
                    {
                        if (p.ID.Equals("steel"))
                        {
                            player.health = -1;
                            player.notHit = false;
                            p.active = false;
                        }
                        else p.active = false;

                        player.applyDamage(p.damage);
                        applyRumble(player, 0.5f, 0, 500);
                        player.score += p.value;
                        applyRumble(player, 0.5f, 0, 500);
                    }
                }

                // Collision detection between the player and background
                foreach (Scenery b in collidableBackground)
                {
                    if (player.checkCollision(b))
                    {
                        player.notHit = false;
                        player.health = 0; 
                    }
                }
            }

            destroyPlayer(player, gameTime);

            if (player.reset)
            {
                if (player.visible) { player.visible = false; }
                else { player.visible = true; }

                if (gameTime.TotalGameTime.Ticks - player.resetTimer.Ticks > (3 * 1000 * 1000 * 10))
                {
                    player.visible = true;
                    player.active = true;
                    player.reset = false;
                }
            }
        }

        public void doEndGame(Boolean passed)
        {
            if (!passed)
            {
                if (levelName.Equals("sur") && CurWave > 5 && !settings.achievements.sur25.achived)
                {
                    settings.achievements.sur25.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.sur25), null);
                }
                else if (levelName.Equals("sur") && CurWave > 50 && !settings.achievements.sur50.achived)
                {
                    settings.achievements.sur50.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.sur50), null);
                }
                else
                {
                    ScreenManager.AddScreen(new GameOverScreen(players, settings, levelName), null);
                }
            }
            if (passed)
            {

                Boolean notHit = false;
                Boolean acc = false;
                foreach (Player p in players)
                {
                    if (p.notHit) notHit = true;
                    if (p.accuracy > 90) acc = true;
                }

                if (escaped == 0 && this.levelName.Equals("ont") && !this.settings.achievements.cityNoEscape.achived)
                {
                    this.settings.achievements.cityNoEscape.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.cityNoEscape), null);
                }
                else if (escaped == 0 && this.levelName.Equals("sk") && !this.settings.achievements.skNoEscape.achived)
                {
                    this.settings.achievements.skNoEscape.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.skNoEscape), null);
                }

                else if (escaped == 0 && this.levelName.Equals("bc") && !this.settings.achievements.bcNoEscape.achived)
                {
                    this.settings.achievements.bcNoEscape.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.bcNoEscape), null);
                }

                else if (levelName.Equals("sur") && !this.settings.achievements.sur25.achived)
                {
                    this.settings.achievements.sur25.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.sur25), null);
                }
                else if (levelName.Equals("sur") && !this.settings.achievements.sur50.achived)
                {
                    this.settings.achievements.sur50.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.sur50), null);
                }
                else if (levelName.Equals("sur") && !this.settings.achievements.sur100.achived)
                {
                    this.settings.achievements.sur100.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.sur100), null);
                }

                else if (acc && this.levelName.Equals("ont") && !this.settings.achievements.cityAim.achived)
                {
                    this.settings.achievements.cityAim.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.cityAim), null);
                }
                else if (acc && this.levelName.Equals("sk") && !this.settings.achievements.skAim.achived)
                {
                    this.settings.achievements.skAim.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.bcAim), null);
                }
                else if (acc && this.levelName.Equals("bc") && !this.settings.achievements.bcAim.achived)
                {
                    this.settings.achievements.bcAim.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.skAim), null);
                }

                else if (notHit && this.levelName.Equals("ont") && !this.settings.achievements.cityNoHits.achived)
                {
                    this.settings.achievements.cityNoHits.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.cityNoHits), null);
                }
                else if (notHit && this.levelName.Equals("sk") && !this.settings.achievements.skNoHits.achived)
                {
                    this.settings.achievements.skNoHits.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.skNoHits), null);
                }
                else if (notHit && this.levelName.Equals("bc") && !this.settings.achievements.bcNoHits.achived)
                {
                    this.settings.achievements.bcNoHits.achived = true;
                    ScreenManager.AddScreen(new AcheiveWinScreen(ScreenManager, settings.achievements.bcNoHits), null);
                }

                else
                {
                    ScreenManager.AddScreen(new WinScreen(players, settings, levelName, escaped), null);
                }
            }
            settings.achievements.saveAchievments();
        }
        
        public Boolean allPlayersDead()
        {
            foreach (Player p in players)
            {
                if (p.alive)
                    return false;
            }
            return true;
        }
        
        public void playSound(SoundEffectInstance sound)
        {
            if (settings.playSound)
            {
                sound.Play();
            }
        }

        /// <summary>
        /// find pigs colliding with the scenery
        /// </summary>
        public void PigSceneryCollision()
        {
            foreach (Pig p in pigs)
            {
                foreach (Scenery s in collidableBackground)
                {
                    if (p.checkCollision(s))
                    {
                        p.active = false;
                        Explosion e = new Explosion(explosionTexture, p.center(), 2);
                        explosions.Add(e);
                    }
                }
            }
        }

        /// <summary>
        /// remove all inactive objects so they aren't drawn anymore
        /// </summary>
        public void removeInActive()
        {                
            // Remove dead pigs
            for (int i = 0; i < pigs.Count; i++)
            {
                if (pigs[i].active == false)
                {
                    // If a steel pig dies, reset the boolean so that another can spawn
                    if (pigs[i].ID.Equals("steel"))
                    {
                        this.steelPigPresent = false;
                    }
                    else if (pigs[i].ID.Equals("basic"))
                    {
                        if (!pigs[i].escaped)
                        {
                            Explosion e = new Explosion(explosionTexture, pigs[i].center(), 1);
                            explosions.Add(e);
                        }
                    }
                    else if (pigs[i].ID.Equals("ninja"))
                    {
                        if (!pigs[i].escaped)
                        {
                            Explosion e = new Explosion(explosionTexture, pigs[i].center(), 1);
                            explosions.Add(e);
                        }
                    }
                    else if (pigs[i].ID.Equals("magic"))
                    {
                        if (!pigs[i].escaped)
                        {
                            Explosion e = new Explosion(explosionTexture, pigs[i].center(), 1);
                            explosions.Add(e);
                        }
                    }
                    else if (pigs[i].ID.Equals("bunny"))
                    {
                        if (!pigs[i].escaped)
                        {
                            Explosion e = new Explosion(explosionTexture, pigs[i].center(), 1);
                            explosions.Add(e);
                        }
                    }
                    else if (pigs[i].ID.Equals("leader"))
                    {
                        this.leaderPigPresent = false;
                        if (!pigs[i].escaped)
                        {
                            Explosion e = new Explosion(explosionTexture, pigs[i].center(), 1);
                            explosions.Add(e);
                        }
                    }
                    else if (pigs[i].ID.Equals("drunk"))
                    {
                        if (!pigs[i].escaped)
                        {
                            Explosion e = new Explosion(explosionTexture, pigs[i].center(), 1);
                            explosions.Add(e);
                        }
                    }
                    
                    // If a suicide pig dies, check all nearby living objects. If they're close enough, do damage to them
                    else if (pigs[i].ID.Equals("suicide"))
                    {
                        if(!pigs[i].escaped)
                        {
                            float dist = 0;

                            // Compare each other pig in the pig list, and do an amount of damage appropriate to the distance
                            // between the dying suicide pig and the living other pig
                            foreach (DynamicObject p in pigs)
                            {
                                dist = Vector2.Distance(pigs[i].center(), p.center());
                                if (0 <= dist && dist < 50) { p.health -= pigs[i].damage; }
                                else if (50 <= dist && dist < 100) { p.health -= 6; }
                                else if (100 <= dist && dist < 150) { p.health -= 1; }
                                if (dist < 100 && p.ID.Equals("suicide"))
                                {
                                    p.health = -1;
                                }
                            }

                            // Then check the distance between a suicide pig and the player, again, do an appropriate amount
                            // of damage to the player based on the distance between them.
                            foreach (Player p in players)
                            {
                                SuicidePigPlayerDamage(p, pigs[i]);
                            }

                            Explosion e = new Explosion(explosionTexture, pigs[i].center(), 2);
                            explosions.Add(e);
                        }
                    }
                    if (!pigs[i].escaped)
                    {
                        playSound(pigDyingSound);
                    }
                    pigs.RemoveAt(i);
                }
            }

            for (int i = 0; i < cornBullets.Count; i++)
            {
                //check if bullet's gone off viewing area
                if (!cornBullets[i].active || cornBullets[i].position.Y > viewport.Height)
                {
                    Explosion e = new Explosion(explosionTexture, cornBullets[i].center(), .5f);
                    explosions.Add(e);
                    cornBullets.RemoveAt(i);
                }
            }
            for (int i = 0; i < ninjaStars.Count; i++)
            {
                //check if stars's gone off viewing area
                if (!ninjaStars[i].active || ninjaStars[i].position.Y < 0 || ninjaStars[i].position.Y > viewport.Height)
                {
                    Explosion e = new Explosion(explosionTexture, ninjaStars[i].center(), .5f);
                    explosions.Add(e);
                    ninjaStars.RemoveAt(i);
                }
            }

            foreach (Player p in players) { p.removeOldBullets(); }


            // Check if a pig has gone off the screen, if it has deactivate it, and increment the amount of escaped pigs
            foreach (Pig p in pigs)
            {
                if (p.position.X < -250 )
                {
                    if (!p.ID.Equals("steel")) escaped += 1;
                    p.active = false;
                    p.escaped = true;
                }
            }

            for (int i = 0; i < powerups.Count; i++)
            {
                if (!powerups[i].active) { powerups.RemoveAt(i); }
            }

            for (int i = 0; i < explosions.Count; i++)
            {
                if (!explosions[i].active) { explosions.RemoveAt(i); }
            }

            if (background.Count > 0)
            {
                if (background[0].rectangle.Right < -50) { background.RemoveAt(0); }
            }
            if (collidableBackground.Count > 0)
            {
                if (collidableBackground[0].rectangle.Right < -50) { collidableBackground.RemoveAt(0); }
            }
            if (slops.Count > 0)
            {
                if (!slops[0].Active) { slops.RemoveAt(0); }
            }
        }

        public void SuicidePigPlayerDamage(Player player, Pig pig)
        {
                float dist = Vector2.Distance(pig.center(), player.center());
                if (0 <= dist && dist < 50) 
                { 
                    player.applyDamage(pig.damage);
                    applyRumble(player, 0.8f, 0, 500);
                }
                else if (50 <= dist && dist < 100) 
                { 
                    player.applyDamage(pig.damage/2);
                    applyRumble(player, 0.5f, 0, 500);
                }
                else if (100 <= dist && dist < 150) 
                { 
                    player.applyDamage(pig.damage/4);
                    applyRumble(player, 0.2f, 0, 500);
                }
        }


        /// <summary>
        /// update the position of bullets in the game, check if they
        /// have gone off screen, if so remove them
        /// </summary>
        public void updateBullets()
        {
            foreach (Corn c in cornBullets) { c.Update(); }
            foreach (Star s in ninjaStars) { s.Update(); }
            foreach (Player p in players) { p.updateBullets(); }
            foreach (Slop s in slops) { s.Update(pigs, updateBackgrounds); }
        }

        /// <summary>
        /// check bullets from one player for collision with another
        /// </summary>
        public void bulletPlayerCollisions()
        {
            for (int i = 0; i < players.Count; i++)
            {
                for (int j = 0; j < players.Count; j++)
                {
                    if (players[j].active && players[j].alive && i != j)
                    {
                        foreach (Bullet b in players[i].bullets)
                        {
                            if (b.active && b.checkCollision(players[j]))
                            {
                                players[j].applyDamage(b.damage);
                                Explosion e = new Explosion(explosionTexture, b.center(), .3f);
                                explosions.Add(e);
                                b.active = false;
                            }
                        }
                        foreach (Flame f in players[i].flames)
                        {
                            if (f.active && f.checkCollision(players[j]))
                            {
                                players[j].applyDamage(f.damage);
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// check if corn is hitting the given player
        /// </summary>
        /// <param name="player">the player to check collision for</param>
        public void cornPlayerCollision(Player player)
        {
            foreach (Corn c in cornBullets)
            {
                //check for collision between corn and player
                if (player.active && c.checkCollision(player))
                {
                    c.active = false;
                    player.applyDamage(c.Damage);
                    applyRumble(player, 0.2f, 0, 500);
                }
            }
        }
        
        /// <summary>
        /// check if the corn is hitting the player or the scenery
        /// </summary>
        public void cornCollisions()
        {
            foreach (Player p in players) { cornPlayerCollision(p); }

            foreach (Corn c in cornBullets)
            {    
                //check if player is colliding with background
                foreach (Scenery b in collidableBackground)
                {
                    if (c.checkCollision(b))
                    {
                        c.active = false;
                        Explosion e = new Explosion(explosionTexture, c.center(), .5f);
                        explosions.Add(e);
                    }
                }
            }
        }

        /// <summary>
        /// check if star is hitting the given player
        /// </summary>
        /// <param name="player">the player to check collision for</param>
        public void starPlayerCollision(Player player)
        {
            foreach (Star s in ninjaStars)
            {
                //check for collision between star and player
                if (player.active && s.checkCollision(player))
                {
                    s.active = false;
                    player.applyDamage(s.damage);
                    applyRumble(player, 0.4f, 0, 500);
                }
            }
        }

        /// <summary>
        /// check if the star is hitting the player or the scenery
        /// </summary>
        public void starCollisions()
        {
            foreach (Player p in players) { starPlayerCollision(p); }

            foreach (Star s in ninjaStars)
            {
                //check if player is colliding with background
                foreach (Scenery b in collidableBackground)
                {
                    if (s.checkCollision(b))
                    {
                        s.active = false;
                        Explosion e = new Explosion(explosionTexture, s.center(), .5f);
                        explosions.Add(e);
                    }
                }
            }
        }

        /// <summary>
        /// check if bullets are colliding with objects
        /// </summary>
        /// <param name="time">current game time</param>
        public void bulletCollisions(GameTime time, Player player)
        {
            foreach (Bullet b in player.bullets)
            {
                foreach (Scenery s in collidableBackground)
                {
                    if (b.active && s.checkCollision(b))
                    {
                        b.active = false;
                        Explosion e = new Explosion(explosionTexture, b.center(), .3f);
                        explosions.Add(e);
                    }
                }

                // bullet collision with players
                if (b.active && b.reflected && b.checkCollision(player))
                {
                    player.applyDamage(b.damage);
                    applyRumble(player, 0.1f, 0, 500);
                    b.active = false;
                    Explosion e = new Explosion(explosionTexture, b.center(), .3f);
                    explosions.Add(e);
                }

                foreach (Pig p in pigs)
                {
                    if (b.active && p.active && p.checkCollision(b))
                    {
                        if (p.ID.Equals("steel"))
                        {
                            b.Reflect();
                            p.pushBack();
                        }
                        else
                        {
                            p.health -= b.damage;
                            b.active = false;
                            player.pigsHit++;
                            if (p.health <= 0)
                            {
                                player.score += p.value;
                                p.active = false;
                                if (rand.Next(1, POWERUP_CHANCE) == 1)
                                {
                                    PowerUp pu = new PowerUp(p.center(), this.content, time);
                                    powerups.Add(pu);
                                }
                            }
                        }  
                    }
                }

                foreach (Corn c in cornBullets)
                {
                    if (b.active && c.active && c.checkCollision(b))
                    {
                        c.active = false;
                        b.active = false;
                        player.score += c.value;
                    }
                }

                foreach (Star s in ninjaStars)
                {
                    if (b.active && s.active && s.checkCollision(b))
                    {
                        s.active = false;
                        b.active = false;
                        player.score += s.value;
                    }
                }
            }
            foreach (Flame f in player.flames)
            {
                foreach (Scenery s in collidableBackground)
                {
                    if (f.active && f.checkCollision(s))
                    {
                        f.active = false;
                    }
                }

                foreach (Pig p in pigs)
                {
                    if (f.active && p.active && p.checkCollision(f))
                    {
                        if (!p.ID.Equals("steel"))
                        {
                            if(p.ID.Equals("suicide"))
                            {
                                p.health -= f.damage * 4;
                            }
                            else
                            {
                                p.health -= f.damage;
                            }
                            if (!p.hitByFlame)
                            {
                                p.hitByFlame = true;
                                player.pigsHit++;
                            }
                            if (p.health <= 0)
                            {
                                player.score += p.value;
                                p.active = false;
                                if (rand.Next(1, POWERUP_CHANCE) == 1)
                                {
                                    PowerUp pu = new PowerUp(p.center(), this.content, time);
                                    powerups.Add(pu);
                                }
                            }
                        }
                    }
                }


                foreach (Corn c in cornBullets)
                {
                    if (f.active && c.active && c.checkCollision(f))
                    {
                        c.active = false;
                        player.score += c.value;
                    }
                }

                foreach (Star s in ninjaStars)
                {
                    if (f.active && s.active && s.checkCollision(f))
                    {
                        s.active = false;
                        player.score += s.value;
                    }
                }
            }


            foreach (Bomb b in player.bombs)
            {
                foreach (Scenery s in collidableBackground)
                {
                    if (b.active && b.checkCollision(s))
                    {
                        player.ExplodeBomb(b);
                    }
                }

                foreach (Pig p in pigs)
                {
                    if (b.active && p.active && p.checkCollision(b))
                    {
                        player.ExplodeBomb(b);
                        if (!p.ID.Equals("steel"))
                        {
                            if (p.ID.Equals("suicide"))
                            {
                                p.health -= b.damage * 4;
                            }
                            else
                            {
                                p.health -= b.damage;
                            }
                            if (p.health <= 0)
                            {
                                player.score += p.value;
                                p.active = false;
                                if (rand.Next(1, POWERUP_CHANCE) == 1)
                                {
                                    PowerUp pu = new PowerUp(p.center(), this.content, time);
                                    powerups.Add(pu);
                                }
                            }
                        }
                    }
                }


                foreach (Corn c in cornBullets)
                {
                    if (b.active && c.active && c.checkCollision(b))
                    {
                        player.ExplodeBomb(b);
                        c.active = false;
                        player.score += c.value;
                    }
                }

                foreach (Star s in ninjaStars)
                {
                    if (b.active && s.active && s.checkCollision(b))
                    {
                        player.ExplodeBomb(b);
                        s.active = false;
                        player.score += s.value;
                    }
                }
            }
        }

        /// <summary>
        /// apply a powerup to a player
        /// </summary>
        /// <param name="p">the powerup to apply</param>
        private void applyPowerUp(Player player, PowerUp p)
        {
            p.active = false;
            if (p.name.Equals("bacon")) { player.health += 10; }
            else if (p.name.Equals("tri")) { player.fireMode = 1; player.minShootTime = TimeSpan.FromSeconds(.22f); }
            else if (p.name.Equals("bomb")) { player.fireMode = 2; player.minShootTime = TimeSpan.FromSeconds(.5f); }
            else if (p.name.Equals("flame")) { player.fireMode = 3; player.minShootTime = TimeSpan.FromSeconds(.03f); }
        }

        /// <summary>
        /// add slop to the screen at the position of the given players aimer
        /// </summary>
        /// <param name="currentPlayer">the player that's adding slop</param>
        public void addSlop(Player currentPlayer, GameTime gameTime)
        {
            if ((gameTime.TotalGameTime - currentPlayer.prevSlopTime) > currentPlayer.minSlopTime)
            {
                currentPlayer.prevSlopTime = gameTime.TotalGameTime;
                Slop slop = new Slop();
                Vector2 startPosition = new Vector2(currentPlayer.position.X + currentPlayer.Width/4, currentPlayer.Height / 2 + currentPlayer.position.Y);
                Vector2 endPosition = new Vector2(currentPlayer.aimer.Position.X, currentPlayer.aimer.Position.Y);
                slop.Initialize(slopTexture, startPosition, endPosition);
                slops.Add(slop);
            }
        }

        public void drawStats(SpriteBatch spriteBatch)
        {
            int score = 0;
            foreach (Player p in players) score += p.score;

            spriteBatch.Draw(this.ScoreArea, new Vector2(0, 0), Color.White);
            if (settings.numberOfPlayers == 1)
            {
                spriteBatch.DrawString(scoreFont, "Health:", new Vector2(5, 4), Color.White);
                spriteBatch.DrawString(scoreFont, ((int)(players[0].health)).ToString(), new Vector2(85, 4), Color.LawnGreen);
                spriteBatch.DrawString(scoreFont, "Accuracy:", new Vector2(175, 4), Color.White);
                spriteBatch.DrawString(scoreFont, players[0].accuracy + "%", new Vector2(275, 4), Color.LawnGreen);
            }
            if (settings.numberOfPlayers > 1)
            {
                spriteBatch.DrawString(scoreFont, "Health:", new Vector2(5, 4), Color.White);

                if (players[0].alive)
                {
                    spriteBatch.DrawString(scoreFont, " P1:", new Vector2(85, 4), Color.White);
                    spriteBatch.DrawString(scoreFont, ((int)(players[0].health)).ToString(), new Vector2(120, 4), Color.LawnGreen);
                }
                if (players[1].alive)
                {
                    spriteBatch.DrawString(scoreFont, "P2:", new Vector2(175, 4), Color.White);
                    spriteBatch.DrawString(scoreFont, ((int)(players[1].health)).ToString(), new Vector2(210, 4), Color.LawnGreen);
                }
            }
            if (settings.numberOfPlayers > 2 && players[2].alive)
            {
                spriteBatch.DrawString(scoreFont, "P3:", new Vector2(255, 4), Color.White);
                spriteBatch.DrawString(scoreFont, ((int)(players[2].health)).ToString(), new Vector2(290, 4), Color.LawnGreen);
            }
            if (settings.numberOfPlayers > 3 && players[3].alive)
            {
                    spriteBatch.DrawString(scoreFont, "P4:", new Vector2(345, 4), Color.White);
                    spriteBatch.DrawString(scoreFont, ((int)(players[3].health)).ToString(), new Vector2(380, 4), Color.LawnGreen);
            }
            if (settings.numberOfPlayers > 4 && players[4].alive)
            {
                    spriteBatch.DrawString(scoreFont, "P5:", new Vector2(425, 4), Color.White);
                    spriteBatch.DrawString(scoreFont, ((int)(players[4].health)).ToString(), new Vector2(460, 4), Color.LawnGreen);
            }
            spriteBatch.DrawString(scoreFont, "Score: ", new Vector2(520, 4), Color.White);
            spriteBatch.DrawString(scoreFont, score.ToString(), new Vector2(600, 4), Color.LawnGreen);

            spriteBatch.DrawString(scoreFont, "Lives:", new Vector2(viewport.Width - 350, 4), Color.White);

            if (lives < 4)
            {
                for (int i = 1; i <= lives; i++)
                {
                    int j = 40;
                    spriteBatch.Draw(heartTexture, new Vector2(viewport.Width - 310 + j * i, 4), Color.White);
                }
            }
            else
            {
                spriteBatch.Draw(heartTexture, new Vector2(viewport.Width - 270, 4), Color.White);
                spriteBatch.DrawString(scoreFont, lives.ToString(), new Vector2(viewport.Width - 240, 5), Color.LawnGreen);
            }

            spriteBatch.DrawString(scoreFont, "Escaped:", new Vector2(viewport.Width - 150, 4), Color.White);
            spriteBatch.DrawString(scoreFont, escaped.ToString(), new Vector2(viewport.Width - 50, 4), Color.LawnGreen);

        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public void commonDraw(GameTime gameTime)
        {
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied);

            //draw non-collidable background objects
            foreach (Scenery b in background){ b.Draw(spriteBatch); }

            //draw the corn bullets
            foreach (Corn c in cornBullets) { c.Draw(spriteBatch); }

            //Draw the ninja stars
            foreach (Star s in ninjaStars) { s.Draw(spriteBatch); }

            foreach (Player p in players) { p.drawBullets(spriteBatch); }
            
            //draw the collidable background
            foreach (Scenery s in collidableBackground) { s.Draw(spriteBatch); }

            //draw the slop
            foreach (Slop s in slops) { s.Draw(spriteBatch); }

            //draw the pigs
            foreach (Pig p in pigs) { p.Draw(spriteBatch); }

            foreach (PowerUp p in powerups) { p.Draw(spriteBatch); }
            foreach (Explosion e in explosions) { e.Draw(spriteBatch); }

            foreach (Player p in players) { p.Draw(spriteBatch); }

            drawStats(spriteBatch);
        }

        public Player getLowestPlayer()
        {
            Player low = players[0];
            foreach (Player p in players)
            {
                if (p.health < low.health && p.alive)
                {
                    low = p;
                }
            }
            return low;
        }

        public void addBasic(float x, float y)
        {
            Basic_Pig p = new Basic_Pig(basicPigTexture, new Vector2(viewport.Width + x, y), settings.numberOfPlayers);
            pigs.Add(p);
        }

        public void addSuicide(float x, float y)
        {
            SuicidePig p = new SuicidePig(suiPig, new Vector2(viewport.Width + x, y), settings.numberOfPlayers);
            pigs.Add(p);
        }

        public void addBunny(float x, float y)
        {
            Bunny_Pig p = new Bunny_Pig(bunnyPigTexture, new Vector2(viewport.Width + x, y), settings.numberOfPlayers);
            pigs.Add(p);
        }

        public void addDrunk(float x, float y)
        {
            Drunk_Pig p = new Drunk_Pig(drunkPig, new Vector2(viewport.Width + x, y), settings.numberOfPlayers);
            pigs.Add(p);
        }

        public void addLeader(float x, float y)
        {
            if (!leaderPigPresent)
            {
                Leader_Pig p = new Leader_Pig(this.leaderPig, new Vector2(viewport.Width + x, y), settings.numberOfPlayers);
                pigs.Add(p);
                this.leaderPigPresent = true;
            }
        }

        public void addMagic(float x, float y)
        {
            Magic_Pig p = new Magic_Pig(magicPig, new Vector2(viewport.Width + x, y), settings.numberOfPlayers);
            pigs.Add(p);
        }

        public void addNinja(float x, float y)
        {
            Ninja_Pig p = new Ninja_Pig(ninjaPig, new Vector2(viewport.Width + x, y), settings.numberOfPlayers);
            pigs.Add(p);
        }
        
        public void addSteel(float x, float y)
        {
            if (!this.steelPigPresent)
            {
                SteelPig p = new SteelPig(steelPigTexture, new Vector2(viewport.Width + x, y));
                this.steelPigPresent = true;
                pigs.Add(p);
            }
        }

        public void destroyPlayer(Player player, GameTime gameTime)
        {
            // If the player would die with more than 1 life
            if (player.health <= 0 && lives > 0)
            {
                player.deathCouth++;
                player.health = 100;
                player.fireMode = 0;
                applyRumble(player, 1, 1, 1000);
                playSound(explosionSound);
                Explosion e = new Explosion(explosionTexture, player.center(), 2);
                explosions.Add(e);
                lives -= 1;
                player.reset = true;
                player.resetTimer = gameTime.TotalGameTime;
                player.active = false;
                player.position = new Vector2(100, 100);
                player.minShootTime = TimeSpan.FromSeconds(.15f);
            }
            // Game Over
            else if (player.health <= 0)
            {
                player.deathCouth++;
                playSound(explosionSound);
                Explosion e = new Explosion(explosionTexture, player.center(), 2);
                explosions.Add(e);
                player.reset = true;
                player.resetTimer = gameTime.TotalGameTime;
                player.active = false;
                player.alive = false;
                if (allPlayersDead())
                {
                    doEndGame(false);

                }
            }
        }

    }
}
